package com.wizo.csb;

import java.io.InputStream;
import java.util.Properties;

/**
 * Wrapper around a "real" storage that measures latencies and counts return codes.
 * @author Wizo
 * Todo: this version does not include Measurements.
 */
public class StorageWrapper extends Storage{

	Storage _storage;
	
	public StorageWrapper(Storage storage){
		_storage = storage;
	}
	
	/**
	 * Set the properties for this storage.
	 */
	public void setProperties(Properties p){
		_storage.setProperties(p);
	}
	/**
	 * Get the properties for this storage.
	 */
	public Properties getProperties(){
		return _storage.getProperties();
	}
	
	/**
	 * Initialize any state for this storage.
	 * Called once per storage instance; there is one storage instance per client thread.
	 */
	public void init() throws StorageException{
		_storage.init();
	}
	
	/**
	 * Cleanup any state for this storage.
	 * Called once per storage instance; there is one storage instance per client thread.
	 */
	public void cleanup() throws StorageException{
		_storage.cleanup();
	}
	
	/**
	 * Download an object from the bucket.
	 * 
	 * @param bucket The name of the bucket.
	 * @param name The object name of the object to downlaod.
	 * @return inputStream The inputStream of the object content. If null that means the object does't 
	 * exist or something bad happened.
	 */
	public InputStream download(String bucket, String name){
		long start = System.currentTimeMillis();
		InputStream result = _storage.download(bucket, name);
		long end = System.currentTimeMillis();
		
//		System.out.println("DOWNLOAD: "+(int)(end-start));
		
		return result;
	}
	
	/**
	 * Upload an object from the bucket.
	 * 
	 * @param bucket The name of the bucket.
	 * @param name The object name of the object to upload.
	 * @param inputStream The inputStream of the object content to upload.
	 * @param contentLength The length of the object content.
	 * @param contentType The type of the object content.
	 * @return Zero on success, a non-zero error code on error.
	 */
	public int upload(String bucket, String name, InputStream inputStream, 
			long contentLength, String contentType){
		long start = System.currentTimeMillis();
		int result = _storage.upload(bucket, name, inputStream, contentLength, contentType);
		long end = System.currentTimeMillis();
		
//		System.out.println("UPLOAD: "+(int)(end-start));
		
		return result;
	}
	
	/**
	 * Delete an object for good from bucket.
	 * 
	 * @param bucket The name of the bucket.
	 * @param name The object name of the object to delete.
	 * @return Zero on success, a non-zero error code in error or "not found".
	 */
	public int delete(String bucket, String name){
		long start = System.currentTimeMillis();
		int result = _storage.delete(bucket, name);
		long end = System.currentTimeMillis();
		
//		System.out.println("DELETE: "+(int)(end-start));
		
		return result;
	}
	
	/**
	 * Copy an objectS from bucketS to bucketD and rename it objectD. Replace the metadata depand on the
	 * value of replaceMetadata
	 * 
	 *  @param bucketS The source bucket.
	 *  @param objectS The source object.
	 *  @param bucketD The destination bucket.
	 *  @param objectD The destination object.
	 *  @param replaceData Ture if you want to replace metadata, otherwise you don't.
	 *  @return Zero on success, a non-zero error code on error or "not found".
	 */
	public int copy(String bucketS, String objectS, String bucketD, String objectD, 
			boolean replaceMetadata){
		long start = System.currentTimeMillis();
		int result = _storage.copy(bucketS, objectS, bucketD, objectD, replaceMetadata);
		long end = System.currentTimeMillis();
		
//		System.out.println("COPY: "+(int)(end-start));
		
		return result;
	}
	
	/**
	 * Move an objectS from bucketS to bucketD and rename it objectD, and objectS in bucketS will not
	 * exist any more. Replace the metadata depand on the value of replaceMetadata.
	 * 
	 *  @param bucketS The source bucket.
	 *  @param objectS The source object.
	 *  @param bucketD The destination bucket.
	 *  @param objectD The destination object.
	 *  @param replaceData Ture if you want to replace metadata, otherwise you don't.
	 *  @return Zero on success, a non-zero error code on error or "not found".
	 */
	public int move(String bucketS, String objectS, String bucketD, String objectD, 
			boolean replaceMetadata){
		long start = System.currentTimeMillis();
		int result = _storage.move(bucketS, objectS, bucketD, objectD, replaceMetadata);
		long end = System.currentTimeMillis();
		
//		System.out.println("MOVE: "+(int)(end-start));
		
		return result;
	}
}
